package com.atguigu.blob;

import com.atguigu.util.JDBCUtils;
import org.junit.Test;

import java.sql.Connection;
import java.sql.PreparedStatement;

/**
 * 使用 PreParedStatement 实现批量数据的操作
 * update、delete 本身就具有批量操作的效果
 * 此时的批量操作，主要指的是批量插入，使用 PreParedStatement 如何实现更高效的批量插入？
 * <p>
 * 题目：向goods表中插入20000条数据
 * CREATE TABLE goods(
 * id INT PRIMARY KEY AUTO_INCREMENT,
 * NAME VARCHAR(25)
 * );
 * 方式一：使用Statement
 * Connection conn = JDBCUtils.getConnection();
 * Statement st = conn.createStatement();
 * for(int i = 1;i <= 20000;i++){
 * String sql = "insert into goods(name)values('name_" + i + "')";
 * st.execute(sql);
 * }
 *
 * @author admin
 */
public class InsertTest {
    /**
     * 批量插入的方式二：使用 PreparedStatement
     */
    @Test
    public void testInsert1() throws Exception {

        Connection connection = null;
        PreparedStatement preparedStatement = null;

        try {
            long start = System.currentTimeMillis();

            // 1.获取数据库连接
            connection = JDBCUtils.getConnection();

            // 2.预编译 sql 语句，返回 PreparedStatement 实例对象
            String sql = "insert into goods(name) value(?)";
            preparedStatement = connection.prepareStatement(sql);

            // 3.填充占位符
            for (int i = 1; i < 20000; i++) {
                preparedStatement.setObject(1, "name_" + 1);

                // 4.执行
                preparedStatement.execute();
            }

            long end = System.currentTimeMillis();

            System.out.println("花费的时间为：996835 + " + (end - start));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 5.资源的关闭
            JDBCUtils.closeResource(connection, preparedStatement);
        }
    }

    /**
     * 批量插入的方式三：
     * 1.addBatch()、executeBatch()、clearBatch()
     * 2.mysql服务器默认是关闭批处理的，我们需要通过一个参数，让mysql开启批处理的支持。
     * ?rewriteBatchedStatements=true 写在配置文件的url后面
     * 3.使用更新的mysql 驱动：mysql-connector-java-5.1.37-bin.jar
     */
    @Test
    public void testInsert2() throws Exception {

        Connection connection = null;
        PreparedStatement preparedStatement = null;

        try {
            long start = System.currentTimeMillis();

            // 1.获取数据库连接
            connection = JDBCUtils.getConnection();

            // 2.预编译 sql 语句，返回 PreparedStatement 实例对象
            String sql = "insert into goods(name) value(?)";
            preparedStatement = connection.prepareStatement(sql);

            // 3.填充占位符
            for (int i = 1; i <= 20000; i++) {
                preparedStatement.setObject(1, "name_" + 1);

                // ”攒“ sql
                preparedStatement.addBatch();
                if (i % 500 == 0) {
                    // 4.执行 batch
                    preparedStatement.executeBatch();
                    // 清空 batch
                    preparedStatement.clearBatch();
                }
            }

            long end = System.currentTimeMillis();

            System.out.println("花费的时间为：" + (end - start));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 5.资源的关闭
            JDBCUtils.closeResource(connection, preparedStatement);
        }
    }

    /**
     * 批量插入的方式四：设置连接不允许提交数据
     */
    @Test
    public void testInsert3() throws Exception {

        Connection connection = null;
        PreparedStatement preparedStatement = null;

        try {
            long start = System.currentTimeMillis();

            // 1.获取数据库连接
            connection = JDBCUtils.getConnection();

            // 设置不允许自动提交数据
            connection.setAutoCommit(false);

            // 2.预编译 sql 语句，返回 PreparedStatement 实例对象
            String sql = "insert into goods(name) value(?)";
            preparedStatement = connection.prepareStatement(sql);

            // 3.填充占位符
            for (int i = 1; i <= 20000; i++) {
                preparedStatement.setObject(1, "name_" + 1);

                // ”攒“ sql
                preparedStatement.addBatch();
                if (i % 500 == 0) {
                    // 4.执行 batch
                    preparedStatement.executeBatch();
                    // 清空 batch
                    preparedStatement.clearBatch();
                }
            }

            // 提交数据
            connection.commit();

            long end = System.currentTimeMillis();

            System.out.println("花费的时间为：" + (end - start));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 5.资源的关闭
            JDBCUtils.closeResource(connection, preparedStatement);
        }
    }
}
